package com.jxtc.enterprise.tenant.service;

import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jxtc.enterprise.admin.vo.AdminCompanyImageVO;
import com.jxtc.enterprise.common.constants.FoodMenuStatus;
import com.jxtc.enterprise.common.constants.MealTypeEnum;
import com.jxtc.enterprise.common.constants.PrinterTypeEnum;
import com.jxtc.enterprise.common.entity.*;
import com.jxtc.enterprise.common.enums.ShowVipUserFoodEnum;
import com.jxtc.enterprise.common.exception.ModifyFailureException;
import com.jxtc.enterprise.common.mapper.*;
import com.jxtc.enterprise.common.utils.CurrencyUtil;
import com.jxtc.enterprise.common.vo.CompanyVO;
import com.jxtc.enterprise.common.vo.PaginationResponseVO;
import com.jxtc.enterprise.hr.vo.DepartmentVO;
import com.jxtc.enterprise.hr.vo.MealConfigVO;
import com.jxtc.enterprise.tenant.dto.TenantCompanyCreateDTO;
import com.jxtc.enterprise.tenant.dto.TenantCompanyDTO;
import com.jxtc.enterprise.tenant.dto.TenantCompanyImageDTO;
import com.jxtc.enterprise.tenant.dto.TenantMealConfigDTO;
import com.jxtc.enterprise.tenant.vo.TenantCompanyDeliveryInfoVO;
import com.jxtc.enterprise.tenant.vo.TenantCompanyDetailVO;
import com.jxtc.enterprise.tenant.vo.TenantCompanyImageVO;
import com.jxtc.enterprise.tenant.vo.TenantCompanyMoreDetailVO;
import com.jxtc.enterprise.tenant.vo.companyManage.req.VipUserMealSetInfoUpdateReqVo;
import com.jxtc.enterprise.tenant.vo.companyManage.resp.VipUserMealSetInfoRespVo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
@Slf4j
public class TenantCompanyManagementService {

    private final CompanyMapper companyMapper;
    private final FoodMenuMapper foodMenuMapper;
    private final DepartmentMapper departmentMapper;
    private final DeliverLockerMapper deliverLockerMapper;
    private final UserMapper userMapper;

    public ThreadLocal<String> TL_REQUEST_ID = new ThreadLocal<>();

    public PaginationResponseVO<TenantCompanyDetailVO> queryByPage(String tenantId, String companyName, int status, int current, int size) {
        Page<Company> page = new Page<>(current, size);

        QueryWrapper<Company> wrapper = buildPageQueryWrapper(companyName, status);
        // 仅返回特定租户所负责的公司
        wrapper.eq("tenant_id", tenantId);

        Page<Company> companyPage = companyMapper.selectPage(page, wrapper);
        List<TenantCompanyDetailVO> records = companyPage.getRecords().stream()
                .map(this::toTenantCompanyDetailVO)
                .collect(Collectors.toList());

        return new PaginationResponseVO<>(companyPage.getTotal(), companyPage.getCurrent(), records);
    }

    /**
     * 将数据库中查询到的 Company 数据转换成对应的 VO
     *
     * @param company 数据库中保存的公司信息
     * @return TenantCompanyDetailVO
     */
    private TenantCompanyDetailVO toTenantCompanyDetailVO(Company company) {
        TenantCompanyDetailVO vo = new TenantCompanyDetailVO(company);

        String imageStr = (company.getImages() != null && !company.getImages().isEmpty()) ? company.getImages() : "{}";
        vo.setImages(JSONUtil.toBean(imageStr, TenantCompanyImageVO.class));

        String deliveryInfoStr = (company.getDeliveryInfo() != null && !company.getDeliveryInfo().isEmpty()) ? company.getDeliveryInfo() : "[]";
        List<CompanyDeliveryInfo> deliveryInfoList = JSONUtil.toList(deliveryInfoStr, CompanyDeliveryInfo.class);

        Optional<CompanyDeliveryInfo> lunchOptional = deliveryInfoList.stream()
                .filter(info -> "午餐".equals(info.getDeliveryType()))
                .findAny();
        if (lunchOptional.isPresent()) {
            TenantCompanyDeliveryInfoVO lunchSetting = new TenantCompanyDeliveryInfoVO(lunchOptional.get());
            vo.setLunchSetting(lunchSetting);
        }

        Optional<CompanyDeliveryInfo> dinnerOptional = deliveryInfoList.stream()
                .filter(info -> "晚餐".equals(info.getDeliveryType()))
                .findAny();
        if (dinnerOptional.isPresent()) {
            TenantCompanyDeliveryInfoVO dinnerSetting = new TenantCompanyDeliveryInfoVO(dinnerOptional.get());
            vo.setDinnerSetting(dinnerSetting);
        }

        return vo;
    }

    public CompanyVO save(TenantCompanyCreateDTO dto, String tenantId) {
        Company company = new Company();
        company.setName(dto.getName());
        company.setHrName(dto.getHrName());
        company.setPhoneNumber(dto.getPhoneNumber());
        String defaultCompanyImages = "{\"headImage\":\"https://jxtc-enterprise.oss-cn-shenzhen.aliyuncs.com/%E4%BA%91%E8%81%9A%E6%99%BA%E8%83%BD/head.jpg\",\"middleImage\":\"https://jxtc-enterprise.oss-cn-shenzhen.aliyuncs.com/%E4%BA%91%E8%81%9A%E6%99%BA%E8%83%BD/middle.jpg\",\"noteImages\":[\"https://jxtc-enterprise.oss-cn-shenzhen.aliyuncs.com/%E4%BA%91%E8%81%9A%E6%99%BA%E8%83%BD/note1.jpg\"]}";
        company.setImages(defaultCompanyImages);
        // 初始密码默认 123456，使用 BCrypt 加密后存入数据库
        // company.setPassword(passwordEncoder.encode("123456")); 暂时不加密
        company.setPassword("123456");
        company.setTenantId(tenantId);

        // 新增公司时，默认启用 "午餐"
        List<MealConfig> mealConfigList = buildDefaultMealConfigListByEnum();
        company.setMealsConfig(JSONUtil.toJsonStr(mealConfigList));

        if (companyMapper.insert(company) > 0) {
            CompanyVO companyVO = new CompanyVO();
            companyVO.setId(company.getId());
            companyVO.setName(company.getName());
            companyVO.setHrName(company.getHrName());
            companyVO.setPhoneNumber(company.getPhoneNumber());
            return companyVO;
        }

        throw new ModifyFailureException("新增公司信息失败，请稍后重试");
    }

    private List<MealConfig> buildDefaultMealConfigListByEnum() {
        List<MealConfig> mealConfigList = new ArrayList<>(6);
        for (MealTypeEnum mealType : MealTypeEnum.values()) {
            MealConfig mealConfig = new MealConfig();
            mealConfig.setMealType(mealType.getMealTypeEn());
            mealConfig.setEnabled(false);
            // 默认启用午餐，其它用餐时段默认不启用
            if (mealType.getCode() == MealTypeEnum.LUNCH.getCode()) {
                mealConfig.setEnabled(true);
            }
            mealConfig.setStartTime(mealType.getStartTime());
            mealConfig.setEndTime(mealType.getEndTime());
            mealConfig.setDeliveryTime(mealType.getDeliveryTime());
            mealConfig.setPrintType(mealType.getPrintType());
            mealConfig.setPrintTime(mealType.getPrintTime());

            mealConfigList.add(mealConfig);
        }
        return mealConfigList;
    }

    @Transactional(rollbackFor = Exception.class)
    public void update(TenantCompanyDTO dto) {
        if (dto.getId() == null || dto.getId().isEmpty()) {
            throw new IllegalArgumentException("修改公司信息时，id 字段不能为空");
        }

        Company saved = companyMapper.selectById(dto.getId());
        if (saved == null) {
            throw new IllegalArgumentException("该公司不存在");
        }

        Company company = new Company();
        company.setId(dto.getId());
        company.setName(dto.getName());
        company.setAddress(dto.getAddress());
        company.setThreshold(dto.getThreshold());
        company.setAmount(dto.getAmount());

        if (dto.getHrName() != null && !dto.getHrName().isEmpty()) {
            company.setHrName(dto.getHrName());
        }
        if (dto.getPhoneNumber() != null && !dto.getPhoneNumber().isEmpty()) {
            company.setPhoneNumber(dto.getPhoneNumber());
        }
        if (dto.getPassword() != null && !dto.getPassword().isEmpty()) {
            company.setPassword(dto.getPassword());
        }

        // 更新公司图片相关信息
        String newImages = updateCompanyImage(saved.getImages(), dto.getImages());
        if (newImages != null && !newImages.isEmpty()) {
            company.setImages(newImages);
        }

        // 更新公司午餐/晚餐配送相关信息
        List<TenantMealConfigDTO> mealConfigDTOList = dto.getMealTypes();
        List<MealConfig> mealTypes = mealConfigDTOList.stream()
                .map(this::buildMealConfig)
                .collect(Collectors.toList());

        if (!mealTypes.isEmpty()) {
            company.setMealsConfig(JSONUtil.toJsonStr(mealTypes));
        }

        // 更新成功
        if (companyMapper.updateById(company) > 0) {
            return;
        }

        throw new ModifyFailureException("更新公司信息失败，请稍后重试");
    }

    private MealConfig buildMealConfig(TenantMealConfigDTO dto) {
        MealConfig mealConfig = new MealConfig();
        mealConfig.setMealType(dto.getMealType());
        mealConfig.setEnabled(dto.getEnabled());
        mealConfig.setStartTime(dto.getStartTime());
        mealConfig.setEndTime(dto.getEndTime());
        mealConfig.setDeliveryTime(dto.getDeliveryTime());
        mealConfig.setPrintType(dto.getPrintType());
        mealConfig.setPrintTime(dto.getPrintTime());
        return mealConfig;
    }

    /**
     * 是否停止供餐
     *
     * @param companyId 公司 ID
     * @param cancel    true 表示停止供餐，false 表示继续供餐
     */
    public void supply(String companyId, boolean cancel) {
        boolean exists = companyMapper.exists(new QueryWrapper<Company>().eq("id", companyId));
        if (!exists) {
            throw new IllegalArgumentException("公司不存在");
        }

        Company company = new Company();
        company.setId(companyId);
        company.setStopFlag(cancel);

        if (companyMapper.updateById(company) <= 0) {
            throw new ModifyFailureException("停止供餐失败，请稍后重试");
        }

        UpdateWrapper<FoodMenu> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("company_id", companyId);
        updateWrapper.eq("del_flag", 0);

        FoodMenu foodMenu = new FoodMenu();

        // 如果停止供餐，则菜单置为禁用状态
        if (cancel) {
            foodMenu.setStatus(FoodMenuStatus.DEACTIVE.getStatus());
        } else {
            foodMenu.setStatus(FoodMenuStatus.ACTIVE.getStatus());
        }

        foodMenuMapper.update(foodMenu, updateWrapper);
    }

    /**
     * 软删除公司信息，数据库中 del_flag 置 1
     *
     * @param companyId 公司 ID
     */
    @Transactional(rollbackFor = ModifyFailureException.class)
    public void softDelete(String companyId) {
        boolean exists = companyMapper.exists(new QueryWrapper<Company>().eq("id", companyId));
        if (!exists) {
            throw new IllegalArgumentException("公司不存在");
        }

        Company company = new Company();
        company.setId(companyId);
        company.setDelFlag(true);

        // 1. 删除公司记录
        int companyUpdateCount = companyMapper.updateById(company);
        if (companyUpdateCount != 1) {
            log.error("deleteCompany, delete company failed, companyId: {}, update count: {}", companyId, companyUpdateCount);
            throw new ModifyFailureException("删除公司失败，请稍后重试");
        }
        log.info("/deleteCompany, companyId: {}, update company count: {}", companyId, companyUpdateCount);

        // 2. 删除公司对应的 food_menu 记录
        LambdaQueryWrapper<FoodMenu> foodMenuLambdaQueryWrapper = new LambdaQueryWrapper<FoodMenu>()
                .eq(FoodMenu::getCompanyId, companyId)
                .eq(FoodMenu::getDelFlag, false)
                .select(FoodMenu::getId);
        List<String> foodMenuIdList = foodMenuMapper.selectObjs(foodMenuLambdaQueryWrapper);
        log.info("/deleteCompany, companyId: {}, 待删除的 foodMenuIdList: {}", companyId, foodMenuIdList);
        if (!CollectionUtils.isEmpty(foodMenuIdList)) {
            LambdaUpdateWrapper<FoodMenu> foodMenuUpdateWrapper = new LambdaUpdateWrapper<FoodMenu>()
                    .in(FoodMenu::getId, foodMenuIdList);
            FoodMenu foodMenu = new FoodMenu();
            foodMenu.setDelFlag(true);
            int foodMenuUpdateCount = foodMenuMapper.update(foodMenu, foodMenuUpdateWrapper);
            if (foodMenuUpdateCount != foodMenuIdList.size()) {
                // 如果更新的记录数和查询到需要更新的记录数不一致，记录日志并触发回滚
                log.error("/deleteCompany, update food_menu count: {}, foodMenuIdList size: {}, foodMenuIdList: {}", foodMenuUpdateCount, foodMenuIdList.size(), foodMenuIdList);
                throw new ModifyFailureException("删除公司失败，请联系管理员排查");
            }

            log.info("/deleteCompany, companyId: {}, update food_menu count: {}", companyId, foodMenuUpdateCount);
        }
    }

    /**
     * 修改公司背景图片
     *
     * @param dto 前端传递过来的图片链接信息
     * @return 序列化后的 JSON 字符串
     */
    private String updateCompanyImage(String savedImages, TenantCompanyImageDTO dto) {
        // 如果前端没有传递这个字段，即没有修改该内容，直接返回数据库中原来存储的数据
        if (dto == null) {
            return savedImages;
        }
        // 将数据库中的 JSON 字符串转换成对应的 DTO（空字符串会导致 JSON 转换异常）
        String images = (savedImages != null && !savedImages.isEmpty()) ? savedImages : "{}";

        TenantCompanyImageDTO savedImageDTO = JSONUtil.toBean(images, TenantCompanyImageDTO.class);
        // 修改对应字段为新值
        if (dto.getHeadImage() != null && !dto.getHeadImage().isEmpty()) {
            savedImageDTO.setHeadImage(dto.getHeadImage());
        }
        if (dto.getMiddleImage() != null && !dto.getMiddleImage().isEmpty()) {
            savedImageDTO.setMiddleImage(dto.getMiddleImage());
        }
        if (dto.getNoteImages() != null && !dto.getNoteImages().isEmpty()) {
            savedImageDTO.setNoteImages(dto.getNoteImages());
        }
        return JSONUtil.toJsonStr(dto);
    }


    private QueryWrapper<Company> buildPageQueryWrapper(String companyName, int status) {
        QueryWrapper<Company> wrapper = new QueryWrapper<>();
        if (companyName != null && !companyName.isEmpty()) {
            wrapper.like("name", companyName);
        }

        // 如果查询状态为 "已删除"，del_flag 置 1，否则置 0
        if (status == 4) {
            wrapper.eq("del_flag", 1);
        } else {
            wrapper.eq("del_flag", 0);
        }

        // 如果查询状态为 "正常供餐"，stop_flag 置 0；查询状态为 "停止供餐"，stop_flag 置 1
        if (status == 2) {
            wrapper.eq("stop_flag", 0);
        } else if (status == 3) {
            wrapper.eq("stop_flag", 1);
        }
        return wrapper;
    }

    /**
     * 根据公司id和租户id，查询某个租户负责的公司的详情，包括公司基本信息以及公司的 多餐配置
     *
     * @param companyId
     * @param tenantId
     * @return
     */
    public TenantCompanyMoreDetailVO queryCompanyDetailByCompanyId(String companyId, String tenantId) {
        LambdaQueryWrapper<Company> wrapper = new LambdaQueryWrapper<Company>().eq(Company::getId, companyId).eq(Company::getTenantId, tenantId).eq(Company::getDelFlag, 0);
        Company companyVO = companyMapper.selectOne(wrapper);
        if (companyVO == null) {
            log.warn("queryCompanyDetailByCompanyId, company not found, companyId: {}, tenantId: {}", companyId, tenantId);
            throw new IllegalArgumentException("ID 为 " + companyId + " 的公司不存在");
        }

        QueryWrapper<Department> departmentWrapper = new QueryWrapper<Department>().eq("company_id", companyId);
        List<Department> departments = departmentMapper.selectList(departmentWrapper);

        List<DepartmentVO> departmentVOList = departments.stream()
                .map(department -> new DepartmentVO(department.getId(), department.getName(), department.getAddress()))
                .collect(Collectors.toList());

        return buildCompanyDetailVO(companyVO, departmentVOList);
    }

    /**
     * 拼接信息，用来展示在 编辑公司 按钮弹窗中，公司基本信息，多餐信息
     *
     * @param company
     * @param departmentVOList
     * @return
     */
    private TenantCompanyMoreDetailVO buildCompanyDetailVO(Company company, List<DepartmentVO> departmentVOList) {
        TenantCompanyMoreDetailVO vo = new TenantCompanyMoreDetailVO();
        vo.setId(company.getId());
        vo.setName(company.getName());
        vo.setAddress(company.getAddress());
        vo.setDepartments(departmentVOList);
        vo.setAutoRecharge(company.getAutoRecharge());
        vo.setThreshold(company.getThreshold());
        vo.setAmount(company.getAmount());
        vo.setHrName(company.getHrName());
        vo.setPhoneNumber(company.getPhoneNumber());
        vo.setPassword(company.getPassword());
        vo.setStopFlag(company.getStopFlag());

        // 是否显示客户餐
        boolean showVipUserFoodBtn = company.getShowVipUserFoodBtn().equals(ShowVipUserFoodEnum.SHOW_VIP_USER_FOOD.getValue());
        vo.setShowVipUserFoodBtn(showVipUserFoodBtn);
        vo.setVipUserMealSetName(company.getVipUserMealSetName());
        vo.setVipUserPrinterSn(company.getVipUserPrinterSn());

        String imageStr = (company.getImages() != null && !company.getImages().isEmpty()) ? company.getImages() : "{}";
        vo.setImages(JSONUtil.toBean(imageStr, AdminCompanyImageVO.class));

        String mealsConfig = (company.getMealsConfig() != null && !company.getMealsConfig().isEmpty()) ? company.getMealsConfig() : "[]";
        List<MealConfig> mealTypes = JSONObject.parseArray(mealsConfig, MealConfig.class);

        // 如果 company 表中的 meals_config 字段是默认值 "[]"，则表示该公司还没有配置默认的配送时间相关信息
        // 此时提供默认 mealTypes 信息
        if (mealTypes.isEmpty()) {
            mealTypes = getDefaultMealConfigList();
        }

        List<MealConfigVO> mealTypeVOList = mealTypes.stream()
                .map(this::buildMealConfigVO)
                .collect(Collectors.toList());
        vo.setMealTypes(mealTypeVOList);
        return vo;
    }

    /**
     * 根据 MealTypeEnum 枚举类中的信息构建默认的用餐时段信息
     */
    private List<MealConfig> getDefaultMealConfigList() {
        List<MealConfig> defaultMealConfigs = new ArrayList<>();

        for (MealTypeEnum mealTypeEnum : MealTypeEnum.values()) {
            MealConfig mealConfig = new MealConfig();
            mealConfig.setMealType(mealTypeEnum.getMealTypeEn());
            mealConfig.setStartTime(mealTypeEnum.getStartTime());
            mealConfig.setEndTime(mealTypeEnum.getEndTime());
            mealConfig.setDeliveryTime(mealTypeEnum.getDeliveryTime());
            mealConfig.setPrintTime(mealTypeEnum.getPrintTime());
            mealConfig.setPrintType(mealTypeEnum.getPrintType());
            // 默认该公司所有订餐时段都是未启用状态
            mealConfig.setEnabled(false);

            defaultMealConfigs.add(mealConfig);
        }

        return defaultMealConfigs;
    }

    /**
     * 将 company 表中的 meals_config 信息转换成前端可用的 mealTypes 信息
     */
    private MealConfigVO buildMealConfigVO(MealConfig mealConfig) {
        MealConfigVO mealConfigVO = new MealConfigVO();
        mealConfigVO.setMealType(mealConfig.getMealType());
        mealConfigVO.setEnabled(mealConfig.getEnabled());
        mealConfigVO.setStartTime(mealConfig.getStartTime());
        mealConfigVO.setEndTime(mealConfig.getEndTime());
        mealConfigVO.setDeliveryTime(mealConfig.getDeliveryTime());
        mealConfigVO.setPrintType(mealConfig.getPrintType());
        mealConfigVO.setPrintTime(mealConfig.getPrintTime());
        return mealConfigVO;
    }


    @Transactional(rollbackFor = ModifyFailureException.class)
    public void bindDeliveryLockerForCompany(String companyId, List<String> deliveryLockerIdList) {
        if (deliveryLockerIdList.isEmpty()) {
            throw new IllegalArgumentException("外卖柜 ID 列表不能为空");
        }

        LambdaUpdateWrapper<DeliveryLocker> updateWrapper = new LambdaUpdateWrapper<DeliveryLocker>().in(DeliveryLocker::getId, deliveryLockerIdList);
        DeliveryLocker deliveryLocker = new DeliveryLocker();
        deliveryLocker.setCompanyId(companyId);
        int updateCount = deliverLockerMapper.update(deliveryLocker, updateWrapper);
        if (updateCount != deliveryLockerIdList.size()) {
            // 如果更新失败，记录一下日志信息，并触发回滚
            log.error("/bindDeliveryLockerForCompany, 更新配送柜失败，companyId: {}, deliveryLockerIdList: {}, updateCount: {}", companyId, deliveryLockerIdList, updateCount);
            throw new ModifyFailureException("绑定配送柜失败，请稍后重试");
        }
    }


    public VipUserMealSetInfoRespVo queryVipUserMealSetInfoByCompanyId(String companyId, String requestIdForDebug) {
        Company company = companyMapper.selectById(companyId);
        if (company == null) {
            log.warn("requestId {}, tenant view, /queryVipUserMealSetInfoByCompanyId, company not exists, companyId: {}", requestIdForDebug, companyId);
            throw new IllegalArgumentException("公司 ID 不存在：" + companyId);
        }

        return buildVipUserMealSetInfoRespVo(company);
    }

    private VipUserMealSetInfoRespVo buildVipUserMealSetInfoRespVo(Company company) {
        VipUserMealSetInfoRespVo vo = new VipUserMealSetInfoRespVo();

        // 是否显示客户餐
        boolean showVipUserFoodBtn = company.getShowVipUserFoodBtn().equals(ShowVipUserFoodEnum.SHOW_VIP_USER_FOOD.getValue());
        vo.setShowVipUserFoodBtn(showVipUserFoodBtn);
        vo.setVipUserMealSetName(company.getVipUserMealSetName());
        // 将数据库中保存的套餐价格单位由 "分" 转换为 "元"
        String vipUserMealSetPriceInYuan = CurrencyUtil.fenToYuan(company.getVipUserMealSetPrice());
        vo.setVipUserMealSetPrice(vipUserMealSetPriceInYuan);
        vo.setVipUserPrinterSn(company.getVipUserPrinterSn());
        // 客户餐打印机类型，1 贴纸打印机，2 小票打印机，见枚举 PrinterTypeEnum
        vo.setVipUserPrinterType(company.getVipUserPrinterType());

        String vipUserCarTypeList = company.getVipUserCarTypeList();
        if (StringUtils.hasText(vipUserCarTypeList)) {
            List<String> carTypeList = Arrays.stream(vipUserCarTypeList.split(","))
                    // 返回的车型列表根据字符串升序排列，不区分大小写
                    .sorted(String::compareToIgnoreCase)
                    .collect(Collectors.toList());
            vo.setVipUserCarTypeList(carTypeList);
        } else {
            // 如果数据库中保存的 vipUserCarTypeList 为空，则返回空列表
            vo.setVipUserCarTypeList(Collections.emptyList());
        }

        String vipUserVisitorTypeList = company.getVipUserVisitorTypeList();
        if (StringUtils.hasText(vipUserVisitorTypeList)) {
            List<String> visitorTypeList = Arrays.stream(vipUserVisitorTypeList.split(",")).collect(Collectors.toList());
            vo.setVipUserVisitorTypeList(visitorTypeList);
        } else {
            // 如果数据库中保存的 vipUserVisitorTypeList 为空，则返回空列表
            vo.setVipUserVisitorTypeList(Collections.emptyList());
        }

        return vo;
    }


    @Transactional(rollbackFor = Exception.class)
    public void editVipUserMealSetInfoByCompanyId(VipUserMealSetInfoUpdateReqVo reqVo, String requestIdForDebug) {
        Company savedCompany = companyMapper.selectById(reqVo.getCompanyId());
        if (savedCompany == null) {
            log.warn("requestId {}, tenant view, /editVipUserMealSetInfoByCompanyId, company not exists, companyId: {}", requestIdForDebug, reqVo.getCompanyId());
            throw new IllegalArgumentException("公司 ID 不存在：" + reqVo.getCompanyId());
        }

        if (reqVo.getShowVipUserFoodBtn() != null) {
            int showVipUserFoodBtn = reqVo.getShowVipUserFoodBtn() ? ShowVipUserFoodEnum.SHOW_VIP_USER_FOOD.getValue() : ShowVipUserFoodEnum.HIDE_VIP_USER_FOOD.getValue();

            Company companyForUpdate = new Company();
            companyForUpdate.setId(reqVo.getCompanyId());

            if (!savedCompany.getShowVipUserFoodBtn().equals(showVipUserFoodBtn)) {
                // 数据库中保存的是否显示客户餐与前端传递过来的值不一致的情况下，才修改该字段
                // 否则每次未修改该字段时点击保存，都会导致联动修改 user 表中的数据
                companyForUpdate.setShowVipUserFoodBtn(showVipUserFoodBtn);

                // 联动修改该公司下员工表的 ShowVipFoodBtn 字段
                LambdaUpdateWrapper<User> userLambdaUpdateWrapper = new LambdaUpdateWrapper<User>()
                        .eq(User::getCompanyId, reqVo.getCompanyId())
                        .eq(User::getDelFlag, false);
                User user = new User();
                user.setShowVipFoodBtn(showVipUserFoodBtn);
                int updateCount = userMapper.update(user, userLambdaUpdateWrapper);
                log.info("requestId {}, tenant view, /editVipUserMealSetInfoByCompanyId, 联动修改该公司下员工表的 ShowVipFoodBtn 字段, updateCount: {}", requestIdForDebug, updateCount);
            }

            if (reqVo.getShowVipUserFoodBtn()) {
                // 如果前端选择了显示客户餐这个选项
                // 才能修改客户餐餐品名称和打印机 SN 这两个字段的值
                if (StringUtils.hasText(reqVo.getVipUserMealSetName())) {
                    companyForUpdate.setVipUserMealSetName(reqVo.getVipUserMealSetName().trim());
                }

                if (StringUtils.hasText(reqVo.getVipUserMealSetPrice())) {
                    // 将前端传递过来的套餐价格单位由 "元" 转换为 "分"
                    BigDecimal vipUserMealSetPriceInYuan = new BigDecimal(reqVo.getVipUserMealSetPrice().trim());
                    int vipUserMealSetPriceInFen = CurrencyUtil.yuanToFen(vipUserMealSetPriceInYuan);
                    companyForUpdate.setVipUserMealSetPrice(vipUserMealSetPriceInFen);
                }

                if (StringUtils.hasText(reqVo.getVipUserPrinterSn())) {
                    companyForUpdate.setVipUserPrinterSn(reqVo.getVipUserPrinterSn().trim());
                }

                if (!CollectionUtils.isEmpty(reqVo.getVipUserCarTypeList())) {
                    String carTypeList = reqVo.getVipUserCarTypeList().stream()
                            // 过滤掉空字符串
                            .filter(StringUtils::hasText)
                            // 去掉多余空白符
                            .map(String::trim)
                            // 车型列表根据字符串升序排列，不区分大小写
                            .sorted(String::compareToIgnoreCase)
                            // 以逗号拼接成字符串保存
                            .collect(Collectors.joining(","));
                    companyForUpdate.setVipUserCarTypeList(carTypeList);
                }

                if (!CollectionUtils.isEmpty(reqVo.getVipUserVisitorTypeList())) {
                    String visitorTypeList = reqVo.getVipUserVisitorTypeList().stream()
                            // 过滤掉空字符串
                            .filter(StringUtils::hasText)
                            // 去掉多余空白符
                            .map(String::trim)
                            // 以逗号拼接成字符串保存
                            .collect(Collectors.joining(","));
                    companyForUpdate.setVipUserVisitorTypeList(visitorTypeList);
                }

                if (reqVo.getVipUserPrinterType() != null) {
                    if (reqVo.getVipUserPrinterType().equals(PrinterTypeEnum.XIAO_PIAO_PRINTER.getTypeCode())) {
                        // 如果前端传递的值为 2，则数据库中保存 2（小票打印机）
                        companyForUpdate.setVipUserPrinterType(PrinterTypeEnum.XIAO_PIAO_PRINTER.getTypeCode());
                    } else {
                        // 其它值使用默认的打印机类型：1（贴纸打印机）
                        // 正常情况下前端仅会传递 1 或 2
                        companyForUpdate.setVipUserPrinterType(PrinterTypeEnum.TIE_ZHI_PRINTER.getTypeCode());
                    }
                }
            }

            int companyUpdateCount = companyMapper.updateById(companyForUpdate);
            log.info("requestId {}, tenant view, /editVipUserMealSetInfoByCompanyId, 修改公司信息, companyUpdateCount: {}", requestIdForDebug, companyUpdateCount);
        }
    }
}
